package com.jingtao.rabbitmq.utils;

import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 死信队列工具类
 */
@Component
public class DLXQueue {

    // 死信队列交换机名称
    private static final String DEAD_EXCHANGE = "dead.exchange";
    // 死信队列路由键
    private static final String DEAD_ROUTING_KEY = "dead.routingkey";
    // 交换机名称
    private static final String EXCHANGE = "common.exchange";
    // 路由键
    private static final String ROUTING_KEY = "routingkey";

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Resource
    RabbitAdmin rabbitAdmin;

    /**
     * 发送死信队列消息，过期后进入死信交换机，然后进入死信队列
     * @param queueName 队列名称
     * @param deadQueueName 死信队列名称
     * @param params 消息内容
     * @param expiration 过期时间（毫秒）
     */
    public void sendDLXQueue(String queueName, String deadQueueName, Object params, Integer expiration) {
        // 创建队列和死信队列
        createQueues(queueName, deadQueueName, expiration);

        // 创建交换机
        createExchanges();

        // 发送消息到队列
        rabbitTemplate.convertAndSend(EXCHANGE, ROUTING_KEY, params);
    }

    /**
     * 创建队列和死信队列
     * @param queueName 队列名称
     * @param deadQueueName 死信队列名称
     * @param expiration 过期时间（毫秒）
     */
    private void createQueues(String queueName, String deadQueueName, Integer expiration) {
        Map<String, Object> map = new HashMap<>();
        // 设置队列存活时间
        map.put("x-message-ttl", expiration);
        // 设置死信交换机
        map.put("x-dead-letter-exchange", DEAD_EXCHANGE);
        // 设置死信路由键
        map.put("x-dead-letter-routing-key", DEAD_ROUTING_KEY);

        // 创建队列
        Queue queue = new Queue(queueName, true, false, false, map);
        rabbitAdmin.declareQueue(queue);

        // 创建死信队列
        Queue deadQueue = new Queue(deadQueueName, true, false, false);
        rabbitAdmin.declareQueue(deadQueue);
    }

    /**
     * 创建交换机
     */
    private void createExchanges() {
        // 创建交换机
        DirectExchange directExchange = new DirectExchange(EXCHANGE, true, false);
        rabbitAdmin.declareExchange(directExchange);

        // 创建死信交换机
        DirectExchange deadExchange = new DirectExchange(DEAD_EXCHANGE, true, false);
        rabbitAdmin.declareExchange(deadExchange);
    }
}
